from contextlib import asynccontextmanager
from typing import Dict
from aioredis import Redis, from_url
from fastapi import Request

REDIS_CONFIG = {
    "host": "127.0.0.1",
    "port": 6379,
    "db": 0,
    "decode_responses": False,
}

REDIS_INSTANCES = {
    "img_cache": {
        "host": "127.0.0.1",
        "port": 6379,
        "db": 0,
        "decode_responses": False,
        "key_prefix": "img:"
    },
    "video_cache": {
        "host": "127.0.0.1",
        "port": 6379,
        "db": 0,
        "decode_responses": False,
        "key_prefix": "video:"
    },
    "me_word_cloud_cache": {
        "host": "127.0.0.1",
        "port": 6379,
        "db": 0,
        "decode_responses": False,
        "key_prefix": "me_word_cloud:"
    }
}


class RedisPool:
    def __init__(self):
        self.clients: Dict[str, Redis] = {}

    @asynccontextmanager
    async def connect(self):
        try:
            for name, config in REDIS_INSTANCES.items():
                self.clients[name] = await from_url(
                    f"redis://{config['host']}:{config['port']}",
                    **{k: v for k, v in config.items()
                       if k not in 'key_prefix'}
                )
            yield self
        finally:
            for client in self.clients.values():
                await client.close()

    def get_client(self, name: str) -> Redis:
        return self.clients[name]

    def generate_key(self, instance: str, key: str) -> str:
        return f"{REDIS_INSTANCES[instance]['key_prefix']}{key}"


def get_redis(request: Request):
    return request.app.state.redis_pool
